home *** CD-ROM | disk | FTP | other *** search
- ;****************************************************************************
- ; 386STEP identifies the stepping level of a 386 chip as B0 or earlier,
- ; B1, or D0 or higher. Thanks to Bob Moote and Richard Smith of Phar Lap
- ; Software for their advice and assistance in preparing this code.
- ;
- ; Copyright (c) 1992 Jeff Prosise
- ; First published in PC Magazine, February 11, 1992
- ;****************************************************************************
-
- .386P
-
- code segment para use16 public 'code'
- assume cs:code,ds:code
- org 100h
- begin: jmp short main
-
- msg db "Stepping level $"
- stepb0 db "B0 or earlier$"
- stepb1 db "B1$"
- stepd0 db "D0 or higher$"
- errmsg db "Error: Not a 386$"
-
- ;****************************************************************************
- ; Procedure MAIN
- ;****************************************************************************
-
- main proc near
- ;
- ; Make sure this is a 386 or 486 by toggling the nested task (NT) bit.
- ;
- pushf ;Push FLAGS
- pop ax ;Pop FLAGS into AX
- mov bx,ax ;Copy result to BX
- and bx,4000h ;Zero all but bit 14
- xor ax,4000h ;Toggle bit 14 in AX
- push ax ;Transfer the result back
- popf ; to the FLAGS register
- pushf ;Push FLAGS
- pop ax ;Pop FLAGS into AX again
- mov cx,ax ;Transfer the result to CX
- and cx,4000h ;Zero all but bit 14 in CX
- xor ax,4000h ;Toggle bit 14 in AX
- push ax ;Restore FLAGS with the
- popf ; original NT bit intact
- cmp bx,cx ;Compare BX and CX
- jne short check486 ;Branch if they're not equal
-
- cpu_error: mov ah,09h ;Display error message and
- mov dx,offset errmsg ; exit
- int 21h
- mov ax,4C01h
- int 21h
- ;
- ; Check for a 486 by toggling the alignment check (AC) bit.
- ;
- check486: mov ebx,esp ;Save ESP
- and esp,0FFFFFFFCh ;Zero the lower two bits
- pushfd ;Push EFLAGS
- pop eax ;Pop it into EAX
- mov ecx,eax ;Copy EFLAGS to ECX
- and ecx,40000h ;Zero all but bit 18
- xor eax,40000h ;Toggle bit 18 in EAX
- push eax ;Copy the result back to
- popfd ; the EFLAGS register
- pushfd ;Push EFLAGS
- pop eax ;Pop EFLAGS into EAX again
- mov ebx,eax ;Transfer the result to EBX
- and ebx,40000h ;Zero all but bit 18 in EBX
- xor eax,40000h ;Toggle bit 18 in EAX
- push eax ;Restore EFLAGS with the
- popfd ; original AC bit intact
- mov esp,ebx ;Restore ESP
- cmp ebx,ecx ;Compare EBX and ECX
- jne cpu_error ;Error if they're not equal
-
- is386: mov ah,09h ;Print "Stepping level"
- mov dx,offset msg
- int 21h
- ;
- ; Test for a stepping level of B0 or earlier by executing an XBTS instruction
- ; and trapping invalid opcode exceptions.
- ;
- mov ax,3506h ;Get interrupt 06h vector
- int 21h ; in ES:BX
- mov ax,2506h ;Point interrupt 06h to
- mov dx,offset invalid_op ; internal address
- int 21h
- mov dx,0 ;Set DX to 0
- mov cx,1 ;Initialize CX for XBTS
- db 0Fh,0A6h,00h ;Execute XBTS (Step B1 or
- ; later will branch to
- ; label INVALID_OP)
- mov dx,1 ;Set DX to 1
- invalid_op: push ds ;Save DS on the stack
- push dx ;Save DX also
- mov dx,bx ;Restore the original
- mov ax,es ; interrupt 06h vector
- mov ds,ax
- mov ax,2506h
- int 21h
- pop dx ;Restore DX and DS
- pop ds
- or dx,dx ;Branch if DX is still set
- jz b1 ; to 0
- mov dx,offset stepb0 ;Load DX with message pointer
- jmp short exit ; and exit if it's not
- ;
- ; Test for stepping level B1 chips by seeing if ECX is properly decremented
- ; after a REP INSB instruction followed by a POP.
- ;
- b1: cld ;Clear direction flag
- mov ax,cs ;Point ES:EDI to scratch
- mov es,ax ; buffer
- mov edi,offset msg
- mov dx,80h ;Load I/O port address
- mov ecx,1 ;Initialize ECX
- push ax ;Push AX onto the stack
- rep insb ;Read string from I/O port
- pop ax ;Pop AX off the stack
- or ecx,ecx ;Branch if ECX is equal to 0
- jz d0
- mov dx,offset stepb1 ;Load DX with message pointer
- jmp short exit ;Jump to exit
- ;
- ; By process of elimination, the chip must be step D0 or higher.
- ;
- d0: mov dx,offset stepd0 ;Load DX with message pointer
- exit: mov ah,09h ;Output string identifying
- int 21h ; the stepping level
- mov ax,4C00h ;Exit
- int 21h
- main endp
-
- code ends
- end begin